package com.khalil.kkadmin.module.logging;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class LoggingMonitorService {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    public List<LoggingError> getLoggingList(long startTimeStamp, long endTimeStamp) {
        String loggingQuerySql = """
                  select e.timestmp as create_time,
                  e.formatted_message as format_message,
                  e.caller_class as class_name,
                  e.caller_method as method_name,
                  e.event_id
                  from logging_event e
                  where e.timestmp between :startTime and :endTime
                """;
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValue("startTime", startTimeStamp);
        parameterSource.addValue("endTime", endTimeStamp);
        List<LoggingError> loggingErrors = jdbcTemplate.query(loggingQuerySql, parameterSource, new BeanPropertyRowMapper<>(LoggingError.class));

        Set<String> eventIds = loggingErrors.stream().map(LoggingError::getEventId).collect(Collectors.toSet());

        if (!eventIds.isEmpty()) {
            String exceptionQuerySql = """
                    select t.event_id,t.trace_line from logging_event_exception t where t.event_id in (:eventIds)
                    """;
            MapSqlParameterSource exceptionParameterSource = new MapSqlParameterSource();
            exceptionParameterSource.addValue("eventIds", eventIds);
            List<LoggingErrorException> loggingErrorExceptions = jdbcTemplate.query(exceptionQuerySql, exceptionParameterSource, new BeanPropertyRowMapper<>(LoggingErrorException.class));

            loggingErrors.forEach(loggingError -> {
                List<LoggingErrorException> exceptions = loggingErrorExceptions.stream().filter(loggingErrorException -> loggingErrorException.getEventId().equals(loggingError.getEventId())).toList();
                loggingError.setExceptionList(exceptions.stream().map(LoggingErrorException::getTraceLine).collect(Collectors.toList()));
            });
        }

        return loggingErrors;
    }
}
